package cn.zyl.demo.common.crypto;

import cn.zyl.demo.common.constant.CommonConstant;
import cn.zyl.demo.common.enums.CharsetEnum;
import cn.zyl.demo.common.enums.MsgEnum;
import cn.zyl.demo.common.exception.CryptoHandlerException;
import cn.zyl.demo.common.permanent.MsgProperties;
import cn.zyl.demo.common.tools.HexTool;
import cn.zyl.demo.common.tools.StringTool;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;

/**
 * Aes256CryptoHandler类说明:AES加解密
 *
 * @author wsz
 * @version v1.0
 * @date 2020-07-22
 */
public class Aes256CryptoHandler extends AbstractCryptoHandler{
    private final static String GENERATOR_TYPE = "AES";
    private final static String SECURE_TYPE = "SHA1PRng";
    /**
     * 加密方法
     *
     * @param input     输入字符
     * @param secretKey 秘钥
     * @return 密文
     * @throws CryptoHandlerException 加解密处理异常
     */
    @Override
    protected String encrypt(String input, String secretKey) throws CryptoHandlerException {
        try {
            if(StringTool.isEmpty(input)){ return input; }
            KeyGenerator e = KeyGenerator.getInstance(GENERATOR_TYPE);
            SecureRandom secureRandom = SecureRandom.getInstance(SECURE_TYPE);
            secureRandom.setSeed(secretKey.getBytes(CharsetEnum.UTF_8.getType()));
            e.init(256, secureRandom);
            SecretKey originalKey = e.generateKey();
            byte[] raw = originalKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(raw, GENERATOR_TYPE);
            Cipher cipher = Cipher.getInstance(GENERATOR_TYPE);
            cipher.init(1, key);
            byte[] byteEncode = input.getBytes(CharsetEnum.UTF_8.getType());
            byte[] bytes = cipher.doFinal(byteEncode);
            return HexTool.byteArr2HexStr(bytes);
        } catch (Exception e) {
            throw new CryptoHandlerException(MsgProperties.get(MsgEnum.ERROR_CRYPTO_FAIL_ENCRYPT),e);
        }
    }

    /**
     * 解密方法
     *
     * @param input     密文
     * @param secretKey 秘钥
     * @return 明文
     * @throws CryptoHandlerException 加解密处理异常
     */
    @Override
    protected String decrypt(String input, String secretKey) throws CryptoHandlerException {
        try {
            if(StringTool.isEmpty(input)){ return input; }
            KeyGenerator e = KeyGenerator.getInstance(GENERATOR_TYPE);
            SecureRandom secureRandom = SecureRandom.getInstance(SECURE_TYPE);
            secureRandom.setSeed(secretKey.getBytes(CharsetEnum.UTF_8.getType()));
            e.init(256, secureRandom);
            SecretKey originalKey = e.generateKey();
            byte[] raw = originalKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(raw, GENERATOR_TYPE);
            Cipher cipher = Cipher.getInstance(GENERATOR_TYPE);
            cipher.init(2, key);
            byte[] byteContent = HexTool.hexStr2ByteArr(input);
            byte[] byteDecode = cipher.doFinal(byteContent);
            return new String(byteDecode, CharsetEnum.UTF_8.getType());
        }  catch (Exception e) {
            throw new CryptoHandlerException(MsgProperties.get(MsgEnum.ERROR_CRYPTO_FAIL_DECRYPT),e);
        }
    }

    public static void main(String[] args) {
        AbstractCryptoHandler cryptoHandler = new Aes256CryptoHandler();
        System.out.println(cryptoHandler.encrypt("15479532321", CommonConstant.CRYPTO_SECRET_KEY_TEST));
        System.out.println(cryptoHandler.encrypt("12345789497",CommonConstant.CRYPTO_SECRET_KEY_TEST));
        System.out.println(cryptoHandler.decrypt("a01067b10b306fc401f8758a612d8f2b",CommonConstant.CRYPTO_SECRET_KEY_TEST));
        System.out.println(cryptoHandler.decrypt("bf1fb00d65ff6556a99261d38de03254",CommonConstant.CRYPTO_SECRET_KEY_TEST));
    }
}
